﻿using FlyIL.Advance;
using FlyIL.Trace;
using System.Diagnostics;
using static FlyIL.OperandMaker;


namespace FlyIL.Optimizer
{
    class RetPass : SimplfyRoot
    {
        public override bool IsMatch(Context con, Inst node, ExpByTrace expression = null)
            => (node.Opt == Opt.ret);

        /// <summary>
        ///  ret 的情况 
        /// </summary>
        public override void Do(Context self, Inst node, ExpByTrace expression = null)
        {
            var pre = self.GetPreviousIfExist(node);

            var op = (self.Is64) ? _qword_[AssemblerRegisters.Rsp] : _dword_[AssemblerRegisters.Esp];
            var nnn = Tracer.TraceWeak(self, pre, ref op);

            if (nnn != null && nnn.IsValid)
            {
                if (nnn.Calculable)
                {

                    byte index = node.O1.u8;
                    if (self.Is64)
                    {
                        index += 8;
                        //node.lea(AssemblerRegisters.Rsp, ExprRegisters.Rsp + (ulong)index);
                        //self.InsertAfter(node).jmp(nnn.Result);

                        node.jmp(nnn.Result);
                        var leanode = self.InsertBefore(node);
                        leanode.lea(AssemblerRegisters.Rsp, ExprRegister.Rsp + (ulong)index);
                        self.SimplifyOnce(leanode);
                    }
                    else
                    {
                        index += 4;
                        //node.lea(AssemblerRegisters.Esp, ExprRegisters.Esp + (ulong)index);
                        //self.InsertAfter(node).jmp((uint)nnn.Result);

                        node.jmp((uint)nnn.Result);
                        var leanode = self.InsertBefore(node);
                        leanode.lea(AssemblerRegisters.Esp, ExprRegister.Esp + (ulong)index);
                        self.SimplifyOnce(leanode);

                    }
                }
            }

        }

    }
}
